package com.jthinker.blog.dao.impl;

import com.jthinker.blog.bean.entity.Post;
import com.jthinker.blog.bean.enu.PostStatus;
import com.jthinker.blog.bean.enu.SortOrder;
import com.jthinker.blog.bean.vo.PostFilter;
import com.jthinker.blog.bean.vo.QueryResult;
import com.jthinker.blog.dao.PostDao;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Gang Chen
 * Date: 2015/6/26 22:15
 */
@Repository("postDao")
public class PostDaoImpl extends BaseDaoImpl<Post, Long> implements PostDao
{
    @Override
    public QueryResult<Post> queryPagination(PostFilter filter)
    {
        StringBuilder hql = new StringBuilder("from Post p left join fetch p.category left join fetch p.user");
        StringBuilder countHql = new StringBuilder("select count(*) from Post p ");

        StringBuilder subfix = new StringBuilder(" where 1=1 ");

        Map<String, Object> params = new HashMap<String, Object>();
        Long categoryId = filter.getCategoryId();
        if (categoryId != null)
        {
            subfix.append(" and p.category.id=:categoryId");
            params.put("categoryId", categoryId);
        }

        Integer year = filter.getYear();
        if (year != null)
        {
            subfix.append(" and year(p.postDate)=:year");
            params.put("year", year);
        }

        Integer month = filter.getMonth();
        if (month != null)
        {
            subfix.append(" and month(p.postDate)=:month");
            params.put("month", month);
        }

        Long userId = filter.getUserId();
        if (userId != null)
        {
            subfix.append(" and p.user.id=:userId");
            params.put("userId", userId);
        }

        countHql.append(subfix);
        int count = count(countHql.toString(), params);
        if (count == 0)
        {
            return QueryResult.empty();
        }

        hql.append(subfix);

        List<Post> list = list(hql.toString(), filter.getPage(), filter.getPageSize(), "p.postDate", SortOrder.DESC.toString(), params);
        return new QueryResult<Post>(count, list, filter);
    }

    @Override
    public List<Post> queryRecentList(int count)
    {
        String hql = "from Post p where p.status=:status order by p.postDate desc";
        Query query = getSession().createQuery(hql);
        query.setParameter("status", PostStatus.PUBLISH);
        query.setMaxResults(count);

        return query.list();
    }

    @Override
    public List<Object[]> queryArchives()
    {
        String hql = "select p.postDate,count(p.id) from Post p group by concat(year(p.postDate),'-',month(p.postDate)) order by p.postDate desc";
        return getSession().createQuery(hql).list();
    }

    @Override
    public Post readDetail(Long id)
    {
        Criteria criteria = getSession().createCriteria(Post.class);
        criteria.add(Restrictions.eq("id", id)).setFetchMode("category", FetchMode.JOIN).setFetchMode("user", FetchMode.JOIN);
        return (Post) criteria.uniqueResult();
    }

}
